﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using ManagedDLL;

namespace ServerApp
{
    public class Client
    {
        public Guid playerid { get; set; }
        public string playername { get; set; }
        private TcpClient tcpclient;
        private BinaryWriter streamWriter;
        private NetworkStream clientstream;
        private PlayerInfo playerposition;

        public Client(TcpClient c)
        {            
            this.tcpclient = c;
            this.clientstream = tcpclient.GetStream();
            this.playerid = Guid.NewGuid();
            this.streamWriter = new BinaryWriter(clientstream);
        }

        public void SendChatMessage(string playername, string message)
        {
            DataPackageObject d = new DataPackageObject();
            d.parameters = new object[3];
            d.parameters[0] = 1;
            d.parameters[1] = playername;
            d.parameters[2] = message;

            byte[] array = ObjectSerializer.Serialize(d);

            streamWriter.Write(array);
            streamWriter.Flush();
        }

        public void SendPlayerPosition(string playername, PlayerInfo playerposition)
        {           

            DataPackageObject d = new DataPackageObject();
            d.parameters = new object[3];
            d.parameters[0] = 5;
            d.parameters[1] = playername;
            d.parameters[2] = playerposition;

            byte[] array = ObjectSerializer.Serialize(d);

            streamWriter.Write(array);
            streamWriter.Flush();
        }

        public void HandleClientConnection()
        {
            while (true)
            {
                if (!tcpclient.Connected)
                {
                    break;
                }
                else
                {
                    //Inlezen
                    try
                    {
                        byte[] receivedline = new byte[tcpclient.ReceiveBufferSize];
                        clientstream.Read(receivedline, 0, (int)tcpclient.ReceiveBufferSize);
                        DataPackageObject d = ObjectSerializer.Deserialize(receivedline);

                        HandleMessage(d);                        
                    }
                    catch(Exception e)
                    {
                        //Wanneer client disconnected is
                        ClientManager.Instance.RemoveAddClientToListBox(this.playername, 1);
                        ClientManager.Instance.RemoveClient(this);
                        break;
                    }
                }
            }
            tcpclient.Close();
        }

        private void HandleMessage(DataPackageObject d)
        {
            switch ((int)d.parameters[0])
            {
                case 0:
                    //Aanmelden op de server
                    this.playername = (string)d.parameters[1];
                    ClientManager.Instance.AddClient(this, TEAM.SPECTATORS);                    
                    break;
                case 1:
                    //Afmelden server
                    ClientManager.Instance.RemoveClient(this);
                    break;
                case 2:
                    //Select Team
                    switch ((int)d.parameters[1])
                    {
                        case 1:
                            ClientManager.Instance.RemoveClient(this);
                            ClientManager.Instance.AddClient(this, TEAM.ONE);
                            break;
                        case 2:
                            ClientManager.Instance.RemoveClient(this);
                            ClientManager.Instance.AddClient(this, TEAM.TWO);
                            break;
                    }
                    break;
                case 3:
                    //Select Type player
                    break;
                case 4:
                    //Chat
                    ClientManager.Instance.SendAllClientsChatMessage((string)d.parameters[1], this.playername);
                    break;
                case 5:
                    //Player position
                    this.playerposition = (PlayerInfo)d.parameters[1];
                    ClientManager.Instance.SendAllPlayersPlayerPosition(this.playerposition, this.playerid);
                    break;
            }
        }
    }
}
